#ifndef ROCKET_NET_EVENTLOOP_H
#define ROCKET_NET_EVENTLOOP_H

#include <functional>
#include <pthread.h>
#include <queue>
#include <set>

#include "../common/mutex.h"
#include "fd_event.h"
#include "timer.h"
#include "wakeup_fd_event.h"

namespace rocket {

class EventLoop {
  public:
    EventLoop();

    ~EventLoop();

    void loop();

    void wakeup();

    void stop();

    void addEpollEvent(FdEvent *event);

    void deleteEpollEvent(FdEvent *event);

    bool isInLoopThread();

    void addTask(std::function<void()> cb, bool is_wake_up);

    void addTimeEvent(TimerEvent::s_ptr event);

    bool isLooping() { return m_is_looping; }

  public:
    static EventLoop *GetCurrentEventLoop();

  private:
    void dealWakeup();

    void initWakeUpFdEvent();

    void initTimer();

  private:
    pid_t m_thread_id;

    int m_epoll_fd{0};
    int m_wakeup_fd{0};

    WakeUpFdEvent *m_wakeup_fd_event{nullptr};

    Timer *m_timer{nullptr};

    bool m_stop_flag{false};

    std::set<int> m_listen_fds;

    std::queue<std::function<void()>> m_pending_tasks;

    Mutex m_mutex;

    bool m_is_looping{false};
};

} // namespace rocket

#endif
